@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `1  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D1:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D1:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu  } 3E:}DISK OPERATING SYSTEM II VERSION COPYRIGHT 1984 ATARI CORP.A. DISK DIRECTORY I. FORMAT DISKB. RUN CARTRIDG*}E J. DUPLICATE DISKC. COPY FILE K. BINARY SAVED. DELETE FILE(S) L. BINARY LOADE. RENAME FILE M. RUN AT ADDRES+}SF. LOCK FILE N. CREATE MEM.SAVG. UNLOCK FILE O. DUPLICATE FILEH. WRITE DOS FILES P. FORMAT SINGLEL !N',}#"&))9(&*)/h)''-&؆莟R'S  vL/ˢ L }Insert DOS 2.0s, type Y Λx -}DEfHI 1莏#q! @ y0ɛ8A0,' ȅ 1 1ild! 1L!NO SUCH ITEMSELECT.} ITEM OR FOR MENU! 0 .z:*{}.|{ 1 0 0JB 18L%|DL/}%DIRECTORY--SEARCH SPEC,LIST FILE?[# 0 0 &|D3" 1L!NOT A DISK FILEN !B 1L!E# 1 !BD0}ED:}:1BJ|DE 1DEBHI 1 h0ߢ 0.1}  0?詛 1 y0YЛ 1 ;#L" ;#L! BL1TYPE "Y" TO DELETE...DELETE FILE SPEC2}COPY--FROM, TO?OPTION NOT ALLOWED736 FREE SECTORS COPYING---D1:DIRECK.COMl# 0|D .L/%#3}##JB|DE 1BHID#E 1#0: B 1L!#͑### B 1#c$0SY4}S1}:## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E 5}1 1HH 0hh|DL%1}:̳# L% #D#EL% 1 0 . .0O% 1L!WILD CARDS NOT A6}LLOWED IN DESTINATION 0 <.|K}N 2 FORMAT. t* 5) 1L!`) 0NΞ 0 L1) 1 L!BAD LOAD FILELOAD FROM WHAT FILE?) 0 ?}0#B 1L!WHAT FILE TO LOCK?) 0 0$B 1L!WHAT FILE TO UNLOCK?DUP DISK-SOURCE,DEST DRIVES?TYPE "Y" IF OK TO US@}E PROGRAM AREACAUTION: A "Y" INVALIDATES MEM.SAV.FE! +L1   `*  70 2 2A} 0.* 1 y0 0)INSERT BOTH DISKS, TYPE RETURN^, 1 y038逍 N, 1L! ,B}C, t*  Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0C}Ξ, 0 }, 1 y0C,ШC, 0K'!" H H 'h h Lx+!EF 5L1L!D,I,HhD}` NOT ENOUGH ROOMINSERT SOURCE DISK,TYPE RETURNINSERT DESTINATION DISK,TYPE RETURNE}`  `8 rL1`-* 1P* 1 y0Y`hhL!NAME OF FILE TO MOVE?- 0 0|DL% <.F},^ 1 70 0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  G}JB|,#P#DE 1 HI BDEHHII 1 B 1 ,^ 1 70,0La- B V,#PH},^ 1 70 0L#L!-* 1P* 1 y0Yj383}mm ݭI}}`8}``|* ? ɛ,`|:-)| / 1L!`DESTINATION CANT BE DOJ}S.SYS0 0H{ 24Δ 28/L!/) 2 Π 2 0 ξK}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-GIVE L}FILE,START,END(,INIT,RUN)O S0 1`BDEPHI V` S0H 1 L!M}0 0 1L~0`PLEASE TYPE 1 LETTER,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥN}A"D|ݤD|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`轤{NAMEO} TOO LONG B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:222 1 LP}!ERROR- 138ɛ+,' 20*.. өr2 1``2TOO MANY DIGITSINVALID HEXAQ}DECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8uR} ECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8u Action! and BBS Express! PRO Tutorial by Thomas M. T}Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet NodU}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copyV}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 2W}) All of the above information is intact.--------------------------------------Welcome to the Action!/PRO tuX}torial.In it, I plan to teach you how towrite command modules for BBS Express!PRO. But to write these, you mustknow the Y}Action! programming language.So this is a 2 for the price of 1tutorial.I strongly suggest you print the filesof this tutZ}orial out. There are anumber of programs that accompany thetext part (the part you are readingnow) and smaller program in[}cluded inthe text part that may take a longexplanation. So instead of tryingto view this on the screen and paging around\} looking for what I amtalking about, having it on paperwould make things easier.First thing you should do is turn onyou]}r computer with the Action! cartridge plugged in.You should see a flashing cursor in the upper left hand corner of thesc^}reen and the words "ACTION! (c)1983 ASC" in inverse letters at thebottom. This is the EDITOR mode.This is where you enter_} and edit yourprogram. The Action! editor is veryversitile. I am using it right nowto write this tutorial.I guess we s`}hould start with the"standard" first program that you seein ANY book that teaches a programminglanguage. The infamous "Hea}llo, World"example.To set aside parts of this text thatshould be entered into the editor, Iwill indent from here on in.b} PROC main() PrintE("Hello, World") RETURNOK, so now what does it mean? The word PROC is a Action! rec}served word(that means you can't name a variable,procedure or function that name).PROC is short for PROCedure and thatsid}mply means it is a section of code.The word "main" comes down to us fromthe language C. A short digression isneeded. Ine} the language Pascal, thelast procedure is the controllingprocedure. It can calls all the otherprocedures and it is not nf}amed.In C, the controlling procedure is the one called "main". But it canbe anywhere in the program.In Action!, we comg}promise. It is named like C, but it must be lastlike Pascal. But in Action!, we don'thave to call it "main", we can callh}it anything we want. But most programmers call it main.Then comes the "()". This mean thereare no parameters. The maii}n PROCcan NEVER have any parameters. If you are wondering what parameters are,we will cover them in a later lesson.Nextj} is the "PrintE()" line. Thisis part of the Action! library. Itprints what ever is between the quotesand puts the cursork} on the left sideof the screen on the next line down.Why is the PrintE() line indented?In Action!, indention and capitalil}zationdo nothing. "PRINTE()", "printe()"and "PrintE()" are exactly the samething. But to keep programs from1 programmerm} to another looking thesame, the "PrintE" is used. And it is indented to show that it belongs tothe PROCecude "main".Lan}stly, is the word "RETURN". This signifies the end of a procedure.When it occures at the end of the"main" procedure, youro} programreturns control back to the Action!cartridge.How do you run this program? Whenit is typed into the editor exactp}lyas shown, you press the CONTROL key,the SHIFT key and the M key at thesame time (I will abrieviate this asM).Yoq}u will hear a buzz and the screen will go blank. There will be ainverse line at the top of the screen.You are now in the r}MONITOR mode. Fromhere you must Compile your program.You press C then the RETURN key. Ifthere are errors, you will get s}amessage telling you so. If you haveerrors, press E and the RETURN keyto go back to the Editor. If not,you press R and t}the RETURN key toRun you program.This is a good place to end lessonone. If you want to experiment untilthe next lesson,u} try adding some morePrintE lines in the program. Like: PROC main() PrintE("Hello World!") PrintE("I av}m programming in") PrintE("Action!") RETURNUntil the next lesson... rintE("Hello World!") PrintE("I aU Action! and BBS Express! PRO Tutorial by Thomas M. x}Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod y}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy z}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 2 {}) All of the above information is intact.--------------------------------------In the last lesson, we went ov |}er howto compile and run a Action! program.We also learned that the last PROCin a program is the first one thatis run. F }}inally, we learned our first Action! library PROC - PrintE.Now we are going to cover varibles.In Action!, you must know w ~}hat typeof values a variable will take onbefore you can use it. This is sothe compiler can set aside the rightamount of }space for that variable.In Action!, we have 3 basic variabletypes: BYTE, INT and CARD.Note: the keywords BYTE and CHAR a }reidentical and can ALWAYS be used inplace of each other.First the BYTE. A BYTE can have avalue from 0 to 255 and that }is all.When you add 1 to a BYTE with avalue of 255 you get 0. The same whenyou subtract 1 from 0 you get 255.BYTE value }s are used for loops andmost other general values.The next basic type is a INT. INTs can have values from -32768 to 3276 }7.If you need to use negative numbers,a INT is the only way to do it.Lastly we have a CARD. CARDs can havevalues from 0 } to 65535. Use CARDswhen you need larger numbers. But65535 is the largest number you canhave. When you add 1 to 65535 y }ouget 0 for an answer.The are no real numbers like 5.7in Action!. Nor are there scientificnotation like 5.8E4.Why doe }s Action! have these restric-tions? I know BASIC programmers aresay "In BASIC we don't have to declare variables and they } can bereal and larger than 65535."But in BASIC, EVERY variable takesup 6 bytes of memory. In Action!,a BYTE takes up 1 } byte and INTs andCARDs take up only 2. And thisis the way the computer reallylooks at numbers. The floatingpoint packa }ge is the thing that reallyslows BASIC down.So we have this chart: size inname bytes low val. high val- }------------------------------------BYTE 1 0 255INT 2 -32768 32767CARD 2 } 0 65535Ok, so how do you use them? Here is a sample program. PROC main() BYTE i Print("Give me a } number. ") i=InputB() PrintBE(i) RETURNThe first line we know. It is required by all Action! progra }m todefine a PROC.The next line declares i and j asvariable of type BYTE. They will onlyhave a value from 0 to 255.Th }e Print statement prints what isbetween the quotes without returningthe carriage after.The i=InputB() line inputs a BYTE }from the keyboard and places its valuein i.j=i set the value of j to be the sameas the value in i. PrintBE(j) prints t }he value of j asa BYTE and returns the carriage. If a number larger than 255 is enteredthe Action! system will take w }hat iscalled the "least significant byte" ofthat number and place that in i. Iwon't go into LSB right now. But ifyou wa }nt to experiment...What if you wanted INTs instead ofBYTEs? PROC main() INT i Print("Give me a number. ") } i=InputI() PrintIE(i) RETURNOK, the last thing I will do in thislesson is the related Input andPrint functi }ons. BYTE bCARD cINT iJust declaring some dummy variables.i=InputI() input a INT c=InputC() input a }CARDb=InputB() input a BYTEPrint("hi") print string without the carriage returnPrintE("hi") print }the string with the carriage returnPrintB(b) print a BYTE without the CR PrintBE(b) pr }int a BYTE with a CRPrintC(c) print a CARD without a CRPrintCE(c) print a CARD with a CRPrintI(i) } print a INT without a carriage returnPrintIE(i) print a INT with a CRNext we will go into expression }s andthe IF statement. carriage returnPrintIE(i) print a INT with a CRNext we will go into expression  Action! and BBS Express! PRO Tutorial by Thomas M. }Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 2}) All of the above information is intact.--------------------------------------In the last lesson we went ove}r variables. The name of a variabledoesn't have to a name like the "i" Iused in the examples. In fact, theyshouldn't} be like that. Variablenames should be descriptive to youknow what their purpose is. InAction!, the only restriction is }thatvariable names start with a letter.They may contain letters and the underline "_" character later in thename. Which }is easier to understand?t=(p*x)+p ortotal_price = (price * tax) + priceThis brings us to our next subject,expressi}ons.Action! supports the following operators. - as in negative numbers. Remember only INT can be negative. } * multiply / divide. This is integer division because Action! doesn't have real numbers. So when you } take 5/2 it is equal to 2 NOT 2.5 MOD This is the remainer when you divide. 5 MOD 2 equals 1 because 5/}2=2 with a remainder of 1 + addition - subtraction Action! also has a number of bit-wiseoperators but we will co}ver those later.I guess a sample program would begood about now. This sample programis a little too long for you to hav}eto type in to your editor. So Iguess this is a good time to say thatwhen this occures, the sample programwill be called} APROG.301This means it is a program with theATUTOR series. It goes with lesson3 and it is the 01 (first) program.To l}oad the program into your Action!editor, you press at the same time. The bottom lineof the editor will} print "Read?"Here you type in the filename and itwill load. Then you can compile and run the program like normal.You }will notice that the variblesare of type INT. I did this so youcan see how Action! handles negativenumbers. Try -32767 a}nd 4 forsample numbers once.You will see that Action! does someweird things when you try to gopast the boundries of the }variabletype. In this case, INT can onlybe -32768 to 32767.Try some nicer numbers to show theprogram works fine. Like }10 and 6.Or any other number you may want totry. You will have to recompile andrerun the program for each differentset o}f values.You may have noticed a PutE() commandin the program. This places acarriage return on the screen. Inother word}s, it just puts a blankline on the screen. I just put itin there to make it easier to read.The next things we will cover} arerelationals. Relationals yield avalue of TRUE or FALSE. An examplemight be: 4=7. This is false.Here is a list of t}he Action!relationals: a=b tells if a and b are equala<>b tests to see if a and b are not equal a#b the same as a}<>b a>b is a greater than ba>=b is a greater than or equal to b a THEN statement statement statement FI}If the relational expression betweenthe brackets is true, Action! willexecute all the statements betweenthe IF line and }the FI line.If the relational is false, Action!will skip all the statments betweenthe IF and FI and start with thestatem}ent after the FI.The statements between the IF and theFI should be indented a few spacesto show that they are dependent o}nthe IF statement. And it also makesit alot easier to read!try this program: PROC main() IF 4>9 THEN Pr}intE("4 is greater than 9") PrintE("Do you believe it?!?") FI PrintE("done") RETURNThe above program }should just printthe word "done". If 4 should happento be equal to 9 today (maybe itsFriday the 13th?) then it would prin}tthe other 2 lines followed by the word"done".This is the end of lesson 3, I willleave you with another program thatis }too big to print here. It iscalled: APROG.302 This is the end of lesson 3, I willleave you with another program thatis 2 Action! and BBS Express! PRO Tutorial by Thomas M. }Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 2}) All of the above information is intact.--------------------------------------Well, I guess its time we star}tedtalking about loops. Loops give usthe ability to repeat a section ofcode over and over again untilwe want it to stop.}The section of code we want to repeatis marked off with a DO at the startand a OD at the end. PROC main() DO } Print("Hello!! ") OD RETURNThis is print Hello!! over and overand there is no way to stop it otherthan pressing t}he BREAK key orthe RESET key. So we need a wayto control the number of timesa loop get executed. Action!provides us wit}h 3 ways.The first and probably the leastpowerful is the FOR loop. It is themost used loop. Then why do I sayit is the} least powerful? Becauseit executes a loop a fixed number oftimes. PROC main() BYTE i FOR i=1 TO 8 DO } PrintBE(i) OD RETURNThis program just prints the numbers1 to 8 vertically on the screen. ANYcommands can be} places between theDO and the OD and they will getexecuted 8 times.The next loop controller Action!gives us it the WHILE} loop. It lookslike this: WHILE (a condition is true) DO ODThe WHILE loop evaluates its condition at the top of }the loop, soif the condition is FALSE to beginwith, the loop will never execute.Try program APROG.401 to see.The last ty}pe of loop control Action!gives us is the UNTIL loop. DO statements UNTIL (condition is true) ODThe major diffe}rence between the WHILEand the UNTIL is that the UNTIL getevaluated at the bottom of the loop.This means it will be execut}ed atonce. After it is executed once, ifthe condition is FALSE it will getexecuted again. DO PutE() PrintE("Pr}ess any key or 0") PrintE("to exit") i=InputB() UNTIL i=0 ODIf the condition i=0 is TRUE the loopexits.The l}ast loop command I saved for lastto mention because in theory, it isnever needed. I say in theory becausein the REAL worl}d it can be useful.The command name is EXIT. Letssay your program has to input alarge number. And the next numbersare }divided into the bug numberuntil the answer gets down below10. But if the user inputs a 0 todivide into, the is very bad }sincea division by 0 doesn't exist.Look at program APROG.402 for thisprogram. You will notice that thedivison is not wh}at you would expect.That is because Action! only has wholenumbers.In Action! if you: PrintBE( 1 / 3)That is take 1 d}ivided by 3, you willget 0, NOT .33333Action! has no decimal notation.I am getting of the subject but Ifeel that since i}t is used in the program it is a good idea to explainit.Anyway, the EXIT command is good whenyou use it in emergency sit}uations,when you have to get out of a loopin a hurry.A EXIT is also useful when you havealot of conditions on when to en}da loop.Like: UNTIL (the user answers yes ANDthe record number =0 AND you haven'treached the end of the file AND youare}n't running out of memory space)I haven't gone into the actual Action!statements of those situation yet soI put them in w}ords. But you getthe picture, there are 4 conditionsto end this loop.The better thing to do is just have 1or 2 conditio}ns in the UNTIL statementand put the others in IF FI withcan EXIT.MOST other times, if you must havean EXIT in your loop} to make it workright, you have chosen the wrongtype of loop.APROG.403 compares doing the sameloop with the 3 looping st}atements.Remember, each time a program mustdo a loop, it is up to you, theprogrammer, do decide which type ofloop to use.} For APROG.403, tryand guess which one is BEST. Theyall work, but one is best for whatI am trying to accomplish.That's} it for Action!'s looping commands. In the next file, wewon't be going into any new Action!commands. It will cover some}editor and monitor commands that willmake your writing and debugging ofAction! programs faster and easier. ll cover someo Action! and BBS Express! PRO Tutorial by Thomas M. }Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 2}) All of the above information is intact.--------------------------------------Well, now it is time to cover }the mostpowerful of all the Action! Printroutines. It is called PrintF forprint formatted.This baby does it all!The f}irst thing PrintF must have ita string in "quotes." If PrintF isused like this, it is just likePrint.command } output------------------------------PrintF("Hello") HelloPrint("Hello") HelloBut if some special charact}ers appearinside the "quotes", PrintF can doanything you want.The first of the special charactersis the %E. That is a pe}rcent signfollowed by an E. This can appearanywhere in the "quotes" and Action!will do a RETURN where the %E appears.He}re is a comparison of the old wayversus PrintFold way-------PutE()PrintE("What is your name?")PrintE("Only 10 charact}ers please.")PutE()new way-------PrintF("%EWhat is your name?%EOnly 10 characters please.%E")It may look a little ha}rder to readbut it actually takes up less memoryand time. Why? Because with eachcall to an output procedure, Action!must} open a channel to the screen,print what you want and then close thescreen. So the old way there are 4opens and closes. }With PrintF thereis only 1.The next special character is the %U.What does the U stand for? It meansUnsigned. INTs are }signed with a +/-so it must be used by BYTEs and CARDs.But how does it know what value toprint where the %U is?Assume a }and b are BYTES. a=5 b=10old way-------PutE()Print("The sum of ")PrintB(a)Print(" and ")PrintB(10)Print(" is ")Pr}intBE(a+b)new way-------PrintF("%EThe sum of %U and %U is %U%E",a,b,a+b)Both print the line:The sum of 5 and 10 is 1}5After the second quote, there is acomma and then the BYTEs that getsubstituted. The first BYTE in thatlist goes with t}he first %U. And soon with the rest.Then what does a %C stand for? %Cprints the value associated with itas a character.} The ATASCII valuefor the letter 'A' is 65. So,PrintF("The letter %C.%E",65)will print:The letter A.This may not s}eem very useful but when you want to print specialgraphics characters it is real nice.Here is a list of special characte}rsand how they output the data in thelist.%I - INT%U - CARD (the U stands for Unsigned) and BYTE %C - print as a c}haracter%H - a Hexdecimal number%E - the RETURN character%% - output the percent sign%S - output as a string (we'll cover} this in a later lesson)So what is wrong with PrintF? Well,it can only print to the screen.Not to a external device }like adisk or your printer. Don't worryabout that now, we'll cover that ina later lesson also.Try APROG.601 for an exam}ple of usingPrintF for handling some complexoutput formats.Well that's is for this installment.Short, sweet and to the p}oint. Next,we will go into the heart of Action!,the ability to call PROCs. or this installment.Short, sweet and to the pO Action! and BBS Express! PRO Tutorial by Thomas M. }Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 2}) All of the above information is intact.--------------------------------------Now its time to learn about PR}OCs.What is a PROC? We already know aboutPROC main() but what else is there?A PROC is an independent block ofcode that }can be called. Ideally,a PROC should use only local variablesand not global. We'll get into that in a minute.You defin}e a PROC the same way youdefine main(). PROC my_proc() local variables statementsRETURN The "my_proc" c}an be any name thatisn't already used by the Action!system.For you BASIC programmers, a PROC islike a GOSUB. But much m}ore powerful.PrintE and the most of the otherroutines we've looked at so far arePROCs that are built in to the Action!ca }rtridge.Let's take a look at a sample.PROC my_proc() BYTE a a=10 PutE() PrintBE(a) RETURNPROC main()  } BYTE a a=5 PutE() PrintBE(a) my_proc() PutE() PrintBE(a)RETURNCan you guess what will be printed?The outpu }t will look like this:5105First 'a' is set to 5 in main().Remember that the last PROC is alwaysthe first one run. Th }e value of'a' is then printed. Then when thecomputer gets to the line "my_proc()"it goes up to the spot where "PROC  }my_proc()" is and starts runningthere. Ok, now we have another 'BYTE a'and we already declared a BYTE a.These }2 "a's" are as different asapples and oranges. They are localto the PROC they were declared in.So 'a' is set to 10 and i}s printed.When the RETURN statement is executed,the computer goes to the next lineafter the call to the PROC. In thiscas}e it will print 'a' again.And it prints 5. But in my_proc weset a=10. Once again, these are2 different variables becaus}e eachcan only be used by the PROC it isdefined in.A even more powerful feature of PROCsit the ability to pass it parame}ters.Parameters and local variables allowPROCs to not know or care anythingabout the outside program. A PROCwill have a }specific task and itwon't care what called it or why.Take a look at APROG.701 for anexample.The call to the PROC in main}() lookslike "square(num)". Action! takeswhatever num is equal to and placesin the variable "number" inPROC square(BYTE }number).You can have a number of parametersand they can be any type. You caneven mix types. To pass 2 BYTEs and1 CARD }to a PROC use this:PROC m(BYTE a,b CARD c)and the call would look like:m(10,30,5000)There are commas between like var}iabletypes and a space between differenttypes.You can have PROCs call other PROCs.It's important to understand the useo}f local variables and PROCs. Evenmore so of the PROCs. Next timewe will cover FUNCs, which are similarto PROCs, and the }opposite of localvariables, globals. so of the PROCs. Next timewe will cover FUNCs, which are similarto PROCs, and the ( Action! and BBS Express! PRO Tutorial by Thomas M. !}Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod!}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy!}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 2!}) All of the above information is intact.--------------------------------------Do you remember what a functio!}n isfrom high school algebra? It takean number, performs some operation onit and return only 1 number back.Like:y = f(! }x)where f(x) = x^2So if x=3 then y=9.In Action!, a function is like a PROConly it has a type associated with it.We ca!!}n write the x^2 function inAction! like this.CARD FUNC squared(BYTE x) CARD y y = x * xRETURN(y)PROC main() !"}CARD answer answer = squared(3) PrintCE(answer)RETURNAnd it will output a 9.Notice that there is a variable typeb!#}efore the word FUNC. This tellswhat is going to be returned. A BYTE,CARD or INT can be used. As you cansee, the rest is !$}alot like a PROC.The next different thing is theRETURN statement.Whatever is on the left side of theequals sign in the c!%}all, in thiscase the variable 'answer' willget the same value as what is insidethe () after the word RETURN in theFUNC.!&}You can see that the input routineswe've been using so far are really FUNCs. When you do a: value = InputB()the firs!'}t line of InputB in realitylooks like this.BYTE FUNC InputB()meaning it returns a BYTE to value.When we first talked a!(}bout IF FI, I said that the conditional after theIF returned a TRUE or a FALSE. Inreality, the FALSE is the number 0.An!)}d TRUE is actually any other number.The most common values for TRUE are1 or 255 but ANY positive value willdue.So if you!*} wrote a FUNC that returnsa 0 or a 1, you could use it inplace of a conditional. This is apowerful use of FUNCs.BYTE F!+}UNC values_match(BYTE x,y) BYTE rval rval=0 IF x=10 AND y=20 THEN rval=1 FIRETURN(rval)PROC main() BYTE !,}v1, v2 PrintE("Please give me 2 numbers.") Print("v1 = ") v1=InputB() Print("v2 = ") v2=InputB() IF valu!-}es_match(v1,v2) THEN PrintE("Your values match!!") FIRETURNThis is almost a trivial sample of the power this typ!.}e of construct.If you have seen a program I wroterunning on BBS Express! PRO called"The Wheel", 50% of that program isBYT!/}E FUNCs that return a 1 or a 0 toIF FI statements.Now, what if you need a variable thatwill be used by alot of PROCs and !0}FUNCs? Do you keep sending it asa parameter? Well, you could, butusing globals would be better.We know that using a lo!1}cal variabledoesn't affect any of the othervariable used outside that PROC orFUNC. What if we want to changesomething in!2} the outside program?Again, global variables are theanswer.A global variable is a variable thatis not declared between a!3} PROC andits RETURN or a FUNC and its RETURN.They are declared at the start of theprogram and between PROCs and FUNCs.Th!4}e compiler knows a variable is a global by use of the work MODULE.The word MODULE is assumed asthe first line your program!5}. But itnever hurts to put it in. If youdeclare globals anywhere else in yourprogram (like between PROCs etc.) thenyou !6}MUST have the MODULE there.MODULE BYTE score PROC you_win() PrintE("You won this game!!!") score = !7}score +100 RETURN PROC main() you_win() PutE() Print("Your score is: ") PrintCE(score) RETURNYou!8} can see that the value of scorein the main() was increased by the"score = score +100" in you_win().You can't do this with!9} localsbecause when you change a local (thisincludes parameters too) it is onlychanged within that PROC or FUNC.Try to r!:}esist the urge to use allglobals in your programs. Globalsmake bugs nearly impossible to find.And there are times when yo!;}u don'tNEED a variable to change in theoutside program.When I first introduced PROCs I saidthat they were independent bl!<}ocksof code. Using globals makes a PROCdependent on the rest of the program. PROCs I saidthat they were independent bl R Action! and BBS Express! PRO Tutorial by Thomas M. %>}Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod%?}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy%@}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 2%A}) All of the above information is intact.--------------------------------------An ARRAY is a group of numbers%B} thatare the same type. Whether that meansthey are a BYTE, INT or CARD.A string is something like this:"Hello, how are %C}you today?"So why are these 2 concepts begin presented in the same lesson? Becauseto a computer, they are the samething%D}. A string is just an ARRAY ofBYTE values. But since a BYTE anda CHAR are EXACTLY the same thing,we will use CHAR just s%E}o we knowthat we are using that ARRAY as a string instead of just holdingnumbers. There is one smalldifference between s%F}trings andBYTE ARRAYs and we cover that in alittle bit.An ARRAY is a indexed group ofnumbers. Lets say you have 4 peopl%G}eplaying a game and you want to keeptrack of all their scores. Youcould use 4 different variableslike this:PROC print_%H}score() BYTE score1, score2, score3, score4 PrintF("Score 1: %U",score1) PrintF("Score 2: %U",sc%I}ore2) PrintF("Score 3: %U",score3) PrintF("Score 4: %U",score4)RETURNEverytime you needed to do somethingwith a perso%J}ns score, you have tofigure out who is playing and thenuse their particular score variable.A better way is to use an ARRA%K}Y.PROC print_score() BYTE ARRAY score(5) BYTE player FOR player=1 TO 4 DO PrintF("Score %U: %U",player,scor%L}e(player)) ODRETURNNow anytime you need a persons score,you just place that player's numberin score( ) and it is given%M} to you.The declaration of an ARRAY istype ARRAY name(dimension)type can be any of the fundamentaltypes; BYTE (CHAR), %N}INT or CARD.The dimension is how big the ARRAY isgoing to be. In Action!, ARRAYs gofrom 0 to dimension-1. That is whywe%O} declared score(5), now the playernumbers go from 0 to 4. We could haveused score(4) but then the numberswould go from 0 %P}to 3 and humansusually don't think that way.The type has nothing to do with howbig an ARRAY can be. The type iswhat the%Q} ARRAY will hold. Forexample, you can have this:BYTE ARRAY total_pay(5000)Now you can have 5000 employees buteach can %R}only have a pay of 0 to 255.(Sounds familiar huh?)total_pay(1) = 210total_pay(2) = 170total_pay(3) = 250total_pay(4) = %S}100 . . .total_pay(4999) = 30If you want to input a number intoan array you could use:PROC main%T}() CARD ARRAY lottery(10) BYTE i FOR i=1 TO 9 DO lottery(i)=InputB() ODRETURNYou use ARRAY just like any %U}normalvariable, but you must subscript"(i) or something" each time youuse it.So, what is the difference between aARRAY%V} of BYTEs and a string? Thezeroth (0th) BYTE of a string holdsits length. For this reason, youcan't do a direct assignme%W}nt, thecompiler won't let you. Here's what I mean: CHAR ARRAY prompt(30) prompt="What is your guess? "That is ille%X}gal. Instead, Action!provides you with a ton of PROCs andFUNCs to make working with stringseasy.To assign a string vari%Y}able sometext, you use:SCopy(prompt,"What is your guess? ")This just copies what ever is secondinto what ever is first.%Z} So you canalso use:SCopy(again,prompt)This will make the variable "again"equal to the same text as the variable"prom%[}pt". This is assuming that"again" was dimensioned to the samesize or bigger than "prompt".Printing strings is easy, we j%\}ustuse the normal Print() and PrintE()we have always been using. Just now,you use the string name inplace ofthe text. %]} PrintE(prompt)Inputing strings is a little differentthat inputing normal variables.Here we use:InputS(prompt)N%^}otice that it is a PROC and not a FUNC.Action! also has PROCs that takepart of one string and copy theminto another (sub%_}strings) and takinga string and copying into part ofanother (appending or inserting).Look in you Action! manual on howto %`}use these PROCs.Another thing you can't do in Action!is compare string like this:IF prompt=again THEN ...You must use %a}a built in FUNC thatdoes this for you.SCompare(prompt, again)This FUNC returns an INT value. Itreturn a number <0 if p%b}rompt is lessthan again. It return 0 if theyare equal. And it returns a number>0 if prompt is greater than again.This %c}is great for alphabetization. Infact, APROG.902 does a littlealphabetizing.Before I let you go I have to tellyou a litt%d}le somthing I left off ofATUTOR.003.In an IF statement, if the conditionalis not true you can have an ELSEstatment.IF %e}a>b THEN PrintE("A is less than B")ELSE PrintE("A is greater than or") PrintE("equal to B")FIAction! will execute t%f}he second partonly if the first is not true. Youcan also have multiple IFs.IF a>b THEN PrintE("A is less than B")ELSE%g} IF a=b THEN PrintE("A is equal to B") ELSE PrintE("A is greater than or") FIFIIn fact, this happens so oft%q}WB%DOS SYSB*)DUP SYSB$SATUTOR 001B#wATUTOR 002B%ATUTOR 003B$ATUTOR 004BATUTOR 006BATUTOR 007B#ATUTOR 008B.=ATUTOR 009B?tATUTOR 010B)ATUTOR 011BCATUTOR 012B$ATUTOR 013B6CAUTOR 005en thatwe have a special statement for it:the ELSEIF. The next example isthe exact same thing as the above one.IF a>b TH%r}EN PrintE("A is less than B")ELSEIF a=b THEN PrintE("A is equal to B")ELSE PrintE("A is greater than or")FIThe rea%s}son I am mentioning this nowis APROG.901 uses both the ELSE andthe ELSEIF. E PrintE("A is greater than or")FIThe rea$O Action! and BBS Express! PRO Tutorial by Thomas M. )u}Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod)v}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy)w}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 2)x}) All of the above information is intact.--------------------------------------Well, I guess its time to talk)y} aboutfiles. Now, when I say files, I meanboth files and devices. The onlyAtari device that uses files is thedisk drive)z}. But when it comes downto using files and devices, thingsare done the same.Your Atari has a few devices built into it ){}when you turn it on.E: - input and output - This is the standard Atari editor that is used. When you do a Pri)|}ntE() or other simple output, this is the device it goes to. Also, when you do a InputB() this is the device i)}}t comes from. It is the screen and the keyboard combined.C: - input and output - This is the cassette player.)~}P: - output only - This was originally meant to stand for parallel but Atarians now know it as printer. It mak)}es sense that it is for output only, right?S: - output only - This is the screen. This is the device th)}at is opened by the Atari when you do a Graphics command. (We'll cover Graphics later in the tutorial.)K: -)} input only - The keyboard. When you input information from the keyboard, nothing is echoed on the screen.)}There are 2 more devices that we callstandard, even though they aren't built in to you computer. They haveto be loaded )}in before you can usethem.D: - input and output - Your disk drive. DOS must be loaded before you can use it. )} Also, a filename must be supplied when you first open this device.R: - input and output - The RS232 port on the 85)}0 or P:R: Connection. This is used by modems that need the interface.There is also 1 custom device thati)}s "famous" enough to merit mementioning it here.T: - input and output - This is your 1030 or XM301 modem.OK, those ar)}e the devices. How do youuse them? Good thing you asked. Thefirst thing you must do before youcan use a device, is open)} it.Open(1,"K:",4,0)The number "1" is the device number.After you open a device, from the thenon you refer to it by its)} devicenumber.The "K:" is what device you want toopen. It is a string and must eitherbe in "quotes" or a CHAR ARRAYvari)}able.The next number is the command. Usethis chart to find out which commandto use.Input Only - 4Output Only )} - 8Input and output - 12Append to end of file - 9Disk drive directory - 6Since a K: device can o)}nly do input,the number "4" is an easy choice.Just because a device can do inputand output DOES NOT mean you shouldchoos)}e the number 12. If you wantto output to a disk file use 8.The reason the command number 12 isthere is in a situation lik)}e this:If you want to change the 5th BYTEin a file, you read the first 4and then over write the 5th.The last number "0")} is required andthere must always be a "0" there.If you know BASIC, you will see thereis a little difference between the )}order Action! uses and the orderBASIC uses.In BASIC it is like this:OPEN #1,4,0,"K:"The arguments mean the same thing)}s,just a different order.To output to a file, you use thestandard Atari Print PROCs exceptyou put a D (for device) at th)}eend in the proper place. For example,if you want to print a string witha carriage return on the endto a device, you'd u)}se:PrintDE(2,"Hi there")The number "2" is the device numberyou assigned it in the Open(). Thiscan be done to any devic)}e that cando output and the statement will beexactly the same.Here are the output PROCs. PrintD - stringPrintDE )} - string with CRPrintBD - BYTEPrintBDE - BYTE with CRPrintCD - CARDPrintCDE - CARD with CRPrintID - INTPrintI)}DE - INT with CRThe input statements are close to thenormal input FUNCs as well.b=InputBD(1)Input a byte from device )}number 1.Here are the input FUNCs.InputBD - BYTEInputCD - CARDInputID - INTAnd for strings:InputSD(3,name)This get)} a string from device number3 and places it in name.There are 3 more statements you canuse with devices.c=GetD(1) - ge)}t a single character from device number 1PutD(1,c) - put a single character on device 1.PutDE(1)},c) - same but CR afterInputMD(3,name,20) - Get a string from device number 1 and)} only 20 characters long.When you are done with a device, youmust always close it.Close(4) - close )}device number 4.There are a few things that are different when you use D:The first is you must supply afilename. It )}can be 8 characterslong with a 3 character extension.Open(3,"D:MYFILE.DAT",8,0)If you use a DOS that hassubdirectories,)} they can be includedin the device string as well.If you use Open a disk file witha command number of 8, it willcreate a)} new file if it does notalready exist or erase the old fileif it does.When you Open a disk file withcommand number 4, it)} always startsreading at the beginning.It is a good idea to get in the habitof close a device number beforeyou open it j)}ust to make sure it isok to use. If you try to open a device number when it is alreadyopen, you program will bomb.The d)}evice numbers that you are allowed to use are 1 though 7.Lastly, every time you compile anAction! program, a BYTE ARR)}AY isautomaticly declared for you. TheARRAY is called "EOF". EOF holdseither a 0 or a 1 so it can be usedin a IF, WHILE)} or UNTIL statement.When using disk or cassette files,you cannot try to read past the endof the file. If you do try, the)}program will crash.So you have 2 choices, either youhave to save the number of entriesin that file and use a FOR loopto)} read in exactly that number ofentries. Or use EOF.EOF holds a 1 if you are at the endof file and 0 otherwise. Forexam)}ple:EOF(2)If device number 2 is at the end ofthe file, then this will be a 1. Thebest way to use EOF is in a WHILEloo)}p because a WHILE loop checksbefore the loop is run the firsttime.PROC read() BYTE character Close(1) Open(1,"D1)}:ATUTOR.001",4,0) WHILE EOF(1)=0 DO character=GetD(1) Put(character) OD Close(1)RETURNThis PROC prints AT)}UTOR.001 on thescreen character by character. Thefile ATUTOR.001 must be on the disk indisk drive #1 for this program to )}work. Also, you may have noticed thatI didn't call it main() this time.Remember, you don't have to callit main().This )}type of PROC might be good ifyou wrote a game and this will printthe instruction file to the screenfor the user.You may )}also have noticed that readingcharacter by character is not the mostefficient way to do this. A betterway would have been)} to read the wholeline in with a InputSD() and echoit with a PrintE(). But to so this the last line must end with a CRbe)}fore the end of file. If you KNOWthat it does, you can use the nextPROC instead. But, if you areunsure, you don't want t)}o makeassumptions. (By the way, ATUTOR.001does have a CR before the end of fileso it is OK to use this PROC)PROC better)}_read() BYTE ARRAY line(50) Close(1) Open(1,"D1:ATUTOR.001",4,0) WHILE EOF(1)=0 DO InputSD(1,line) Print)}E(line) OD Close(1)RETURN Close(1) Open(1,"D1:ATUTOR.001",4,0) WHILE EOF(1)=0 DO InputSD(1,line) Print(! Action! and BBS Express! PRO Tutorial by Thomas M. -}Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod-}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy-}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 2-}) All of the above information is intact.--------------------------------------We have just finished pretty m-}uch ofthe basics of Action! Now it's timeto get into the more advanced topicthat Action! offers.The first of these is t-}he POINTER.A POINTER does not hold a value likea "normal" variable. Instead it tellsus where that value physically is in-}side your Atari. To declare a POINTER we first have to declare whattype it will point to.BYTE POINTER aCARD POINTER b-}There are 2 new operators that canbe used with POINTERS. If we havea variable i of type INT we canuse this:INT POINTER -}g g=@iThis means g points to i. Well, itreally mean that we have assignedg to point to the same memory locationas i.-} g holds the memory locationof i.Another new operator we now have is: g^=5This says to put the value 5 intothe memo-}ry location that g points to.Try APROG11.001 and try and followwhat is going on. You can see thatPOINTERs are a nice way-} of simulatingthe BASIC POKE command. But Action!has even better ways to accomplishthat.They say "A picture is worth a-}thousand words" to I'll try it now.I'll try and show you this PROCgraphicly. PROC m() CARD c CARD POINTER cp c=1-}0 cp=@c cp^=6RETURNOk, we have 2 objects to begin with: I'll use ? to mean we don't know forsure that these va-}lue hold since wedidn't assign them to anything yet. ? ? cp c When the assignment c=10 c-}ome upthe variable look like this: ? 10 cp cWhen cp=@c is executed, cp is assignedto poin-}t to the memory location thatc occupies. NOT to the value in c. -------| 10 cp -------> cThen, we change -}the value in thelocation cp points to to 6. -------| 6 cp -------> cI hope that helped a little.Have yo-}u ever wanted to change thevalue of parameter you passed to aPROC or FUNC? Well, before now youhave to create a global an-}d not usea parameter at all. POINTERs allowyou to keep PROCs and FUNCsindependent by not using globalsand allowing you t-}o change the valueof a parameter outside of the PROC. PROC add(BYTE POINTER a) a^==+10RETURNPROC main() BYTE a -}a=5 PrintBE(a) add(@a) PrintBE(a)RETURNWell, I bet you are saying, "That'snice, I MIGHT use that once in awhile, -}but big deal otherwise." I amgoing to introduce 2 more types ofnew Action! ideas then you will seethe importance of POINT-}ERs. We are going to leave POINTER for amoment to talk about 2 things. Thefirst is VERY short. It is the Action! dire-}ctive DEFINE. You useDEFINE to clarify your programs andmake them easier to read. And theytake up no extra memory so you-} canuse tons of them without any overhead.DEFINEs simply substitute one thingfor another. We know from a previousAPROG -}that Put(125) clears the screen.But you really can't tell that justby looking at it can you? But CLSlooks like it might m-}ean clear screen.So we can use:DEFINE CLS = "Put(125)"PROC m() CLS Print("hi")Or you can use it like this:DEFIN-}E MAX = "25"PROC any() FOR i=1 TO MAX DO ;read in values OD FOR i=1 TO MAX DO ;print out values OD-}This way, if you want to increase themaximum number of entries, you onlyhave to change the value in MAX, andall the times -}it is used are changed.The next thing is records. You mayhave noticed that when you declarean ARRAY, all the items have -}to bethe same type. All INTs, all CARDsetc. Records allow us to mix typesinto one object.TYPE new = [ BYTE player_numb-}er, points_per_game CARD season_total, lifetime_total ] new bball_player-}We have just made a new type ofvariable. When we use thenew bball_playerit is just likeINT g"new" is the type and -}bball_player isthe variable name. To use a recordwe have "dot notation". That is justa fancy way of saying we do this:-}bball_player.player_number=12bball_player.points_per_game=28bball_player.season_total=300bball_player.lifetime_total=Input-}C()And to retrieve this information wecan just:PrintBE(bball_player.player_number)I think this is a good time to stop.-}We have gone over alot in a shorttime and this stuff is pretty hard toget the hang of right away. And itis probably hard-} to think of whatyou can use this for. And youralso saying, "Hey, you said there would be more with POINTERs!" We'llgo-} over how to get more out ofrecords using POINTERs next time. ey, you said there would be more with POINTERs!" We'llgo,A Action! and BBS Express! PRO Tutorial by Thomas M. 1}Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod1}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy1}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 21}) All of the above information is intact.--------------------------------------Well, as you probably noticed 1}in thelast file that POINTERs and recordsaren't all that usefull by themselves.In fact, I decided not to includea sample 1}program about records becauseI couldn't think of a good example.But, when you mix POINTERs and records you get alot of po1}wer. Youmay have tried to make a ARRAY ofrecords. This is illegal in Action!But, if you use POINTERs to accomplishthis 1}it will work.Also, you cannot have a ARRAY as afield in a record. Since strings arejust CHAR ARRAYs, you can't, forexam1}ple, associate a name with otherinformation about a person. Again,POINTERs make this possible too.Even more, you can't h1}ave ARRAYs ofstrings. You guessed it, POINTERs tothe rescue again. I will be coveringall of these in this lesson. Youd1}on't have to fully understand recordsand POINTERs to use the concepts I amintroducing. You can just copy theroutines, etc1}. and modify them forwhatever use you have in mind. But,a good understanding of POINTERs willallow you to even more power1}ful thingsin Action!First, how do you make an ARRAY ofrecords in Action!? First you haveto decide what your record will1} looklike. TYPE employee=[CARD ssnumber1 BYTE ssnumber2 CARD ssnumber3 1} BYTE department, salary ]Now we have to count up the totalnumber of bytes in the record. CARDsand 1}INTs take up 2 bytes and BYTEstake up 1. So, here we have 2 CARDsand 3 BYTEs for a total of 7. DEFINE size = "7"We ha1}ve to decide how many records wewant to hold. Our company is kind ofsmall, we only have 6 employees. So,6 employees each1} taking up 7 bytes.We have to reserve 42 bytes of memoryto hold our information because6*7=42. BYTE ARRAY company(42)1}Now its time to make that POINTER Ihave been talking about. employee POINTER info 'employee' is the type of record tha1}tthe POINTER will point to. 'info' isthe name of the POINTER.Lastly, you need an equation tofigure out where in memory 1}this reallyis. This equation is the same one wewill use for all advanced record andPOINTER manipulations. info = compa1}ny + (counter * size)That's it!info - The name we gave our POINTERcompany - The ARRAY we used to reserve me1}mory.counter - This is the record number we wish to look at. Since we have 6 employees this wi1}ll be a number from 0 to 5. This can be a constant like 3 or a variable like in a FOR loop.si1}ze - The number of bytes in a record in our DEFINE line.Ok, so how do you use it? Easy...If we want to enter1} employee number3's information. info = company + ( 3 * size) info.ssnumber1 = 392 info.ssnumber2 = 80 info.ssnumbe1}r3 = 4593 info.department = 3 info.salary = 7And if employee #2 got a raise topaycode #10 info = company + ( 4 * si1}ze) info.salary = 10 If you want to print employee #0'ssocial security number: info = company + ( 0 * size) PrintC(1} info.ssnumber1) Print("-") PrintB( info.ssnumber2) Print("-") PrintCE( info.ssnumber3)The numbers in the record ca1}n be usedjust like any other variable. info.department = 4 * 5Or whatever. Here is a little picturethat I hope will h1}elp you to see whatis going on. In case you didn't know,when you declare a ARRAY in Action!,the ARRAY name is actually a 1}POINTERto where the ARRAY is in memory.So, let's say our ARRAY starts atmemory location 16000. Also, I'lluse - to repres1}ent bytes. So a CARDwould have 2 bytes, --. TYPE employee=[CARD ssnumber1 BYTE ssnumber2 1} CARD ssnumber3 BYTE department, salary ]record 0 record 1 record 2-- - --1} - -|-- - -- - -|-- - -- - -|^|16000To get record 1 we use this formula: info = company + ( 1 * size)Sticking in th2}e numbers: info = 16000 + ( 1 * 7) info = 16007So, we move our pointer over 7 bytesto location 16007.record 0 2} record 1 record 2-- - -- - -|-- - -- - -|-- - -- - -| ^ | 16007To get record 2: 2} info = 16000 + ( 2 * 7) info = 16014So, we move our pointer over 14 bytesfrom location 16000 to 16014record 0 r2}ecord 1 record 2-- - -- - -|-- - -- - -|-- - -- - -| ^ | 2} 16014But records can't contain strings. SoPOINTERs must be used again to trickAction!What if you wrote a game 2}where thereare multiple levels. When the firstplayer dies, the second player takesover, right where he left off. Well,y2}ou have to keep track of the playersscore, level and name. The score andlevel are easy with records, but thename? We'd u2}se this: TYPE record = [BYTE level CARD score BYTE name]Why only 1 BYTE for the name?2} Thisis just the first BYTE of the playersname. We'll save more space for itin a second. Count up the bytes without2 } the name BYTE. 1 BYTE and1 CARD = 3 bytes DEFINE offset = "3"We'll save 20 bytes for the name. Soadd the length of th2 }e name and theoffset value for the size. DEFINE size = "23"How many players maximum can play ourgame? We'll just say 2 }8. So,8 * 23 = 184 BYTE ARRAY players(184)Now we need 2 POINTERs. One likenormal, and 1 to point to the name. rec2 }ord POINTER active_player CHAR POINTER his_nameThe first POINTER we use just likewe have been before. active_player 2 }= players + (count * size)But to get the name we use: his_name = active_player + offsetThat's it! We'll so some ass2}ignmentsto record number 4. active_player = players + (4 * size) his_name = active_player + offset active_player.lev2}el=1 active_player.score=0 InputS(his_name)Now lets output player 6. active_player = players + (6 * size) his_name2} = active_player + offset Print("Level: ") PrintBE(active_player.level) Print("Score: ") PrintCE(active_player.score2}) Print("Name: ") PrintE(his_name)Ok, the last situation like theseis if you need an ARRAY of differentsize strings.2} Let's say a you needa program to keep track of yourcustomers first name, lastname andthe last date the ordered from you.2}We'll say the date is of the formmm/dd/yy.How big to we want each field?field size in bytes---------------2}------------------firstname 11lastname 14date 9Try to declare your sizes 1 bi2}ggerbecause strings go from 0 to 1 lessthan their size. This is neededbecause, remember, the 0th byte is thelength of th2}e string.There are no records involved thisconstruct. Here we just usePOINTERs to get around. The firstDEFINE always s2}tarts at 0. DEFINE firstname = "0"If you want to the firstname to be11 bytes, the lastname must startat the 12th byte.2} 0 + 12 = 12 DEFINE lastname = "12"If the lastname is 14 bytes long thedate must start 15 bytes later thanthe lastnam2}e. This means the 27 byteoverall. 12 + 15 = 27 DEFINE date = "27"The total size is 27 + 9 = 36 DEFINE size = "36"2}How many customers do you have? Let'sjust say 100. 100 * 27 = 2700 BYTE ARRAY data(2700)Since we don't have a record2} only characters, our POINTER is just: CHAR POINTER ptrThe POINTER is just like normal ptr = data + (counter * size2})Once again, that's it! For customer#53: ptr = data + (53 * size) Print("First name: ") InputS(ptr + firstname)2} Print("Last name: ") InputS(ptr + lastname) Print("Last order date: ") InputS(ptr + date)APROG12.002 is a full 2}featured phonebook based on this last subject. Print("Last order date: ") InputS(ptr + date)APROG12.002 is a full 02 Action! and BBS Express! PRO Tutorial by Thomas M. 6 }Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod6!}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy6"}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 26#}) All of the above information is intact.--------------------------------------Well, here we are at the last 6$}lessonof Part 1. And I have to apologizefor this one. There are a lot oflittle things I want to mention. Mostof them ha6%}ve nothing to do with any of the others.The first has to do with assigningvariables and routines to specificmemory locat6&}ions. You saw how youcan use POINTERs to change memorylocations (like the backgroundcolor of the screen). But thereis a6'} better way. When you declarea variable, you can assign it to alocation. BYTE bkgnd=710Now any change you make to bkg6(}nd willgo into location 710. bkgnd=0This will change the background colorto black. You can also assignPROCs to speci6)}fic memory locationstoo. That way, if there is a routineloaded into memory, you can callit easily. PROC machine_rout6*}ine=$3500 (BYTE ARRAY s)In Part 2 of this tutorial we will usethis quite a bit.There is another thing you can do withva6+}riables where you declare them. Youcan assign them to a value using[square brackets]. INT i=[-32] BYTE b=[0]So, if 6,}you do a: PrintIE(i) PrintBE(b)you will get -32 0Square brackets are also used forinserting machine lang6-}uage subroutinesin Action! programs. You can usehex values or decimal. You can evenaccess Action! variable. Here's ane6.}xample: [$A9 my_val $2A $8D $CD $04]Action! is very fast but sometimesyou can use that little extra burstfrom machine 6/}language.If you want your Action! code to compile to a specific memory locationyou just insert this at the start ofyour 60}program. SET 14 = $4000 SET $491 = $4000Now you program will compile to location $4000.SET IS NOT LIKE A POKE! SET61} CHANGESMEMORY LOCATIONS AT COMPILE TIME, NOTWHILE IT IS RUNNING!!!If you create a bunch of globalroutines that you in a62}ll your programs,you don't have to type them in eachtime. They can be loaded in whilethe program is compiling. That way63}they are compiled in with your code.You can INCLUDE a file anywhere aslong as if is above whatever PROCsare going to call 64}them. You usually INCLUDE files after the globalvariable and before your first PROC.I have included a Public Domainrunt65}ime package. If you INCLUDEthis when you compile your programs,they will work without the Action!cartridge. It would loo66}k like: INT global1, global2 INCLUDE "D:RUNTIME.ACT" PROC My_first_proc() . . . RETURN67}I mentioned that Action! predeclaressome variables for you. There is animportant one that HAS to be mentioned.Normally68}, if you Action! programfinds an error, it aborts. Yourcan trap errors by making PROCs thatwill execute when an error occ69}ures. PROC my_error(BYTE errno) Print("I found an Error number ") PrintBE(errno) RETURNA BYTE parameter is al6:}ways needed.To make Action! go to this PROC instead of aborting, you just put in: Error = my_errorLastly, Action! has 6;}the same graphicscommand built in as BASIC. I amnot going to go into great detailon graphics. There have been thousands6<}of magazine articles written on thesubject. I will just list the BASICgraphics command and their Action!equivalents.BAS6=}IC Action!-------------------------GRAPHICS 0 Graphics(0)SETCOLOR 1,0,0 SetColor(1,0,0)COLOR 2 6>} color=2POSITION 3,4 Position(3,4)PLOT 10,10 Plot(10,10)DRAWTO 20,20 DrawTo(20,20)I have not listed all t6?}he routinesin the Action! library. There are sound and game controller routines aswell as a ton more.Take a look at you6@}r Action! manualagain. Hopefully you will understandit better than the first time youopened it and said "What does thatm6A}ean?!?"Well, I hope you all have enjoyedthis tutorial. Action! is a great programming language and Action!programmers a6B}re very friendly.Stay tuned for Part 2, writingprograms for BBS Express! Pro. Tomn!programmers a4m Action! and BBS Express! PRO Tutorial by Thomas M. :D}Johnson Available from Villa Video's Bargain Cellar (414) 265-5149 ExpressNet Nod:E}e X11 Action! is copyright of ACS, OSS, ICD.BBS Express! PRO is copyright OrionMicro Systems. This tutorial is copy:F}right Thomas M.Johnson.This tutorial can be distributed underthe following conditions: 1) It is free. 2:G}) All of the above information is intact.--------------------------------------As promised, now we are going :H}to talkabout advanced editor and monitorcommands. Knowing these will makeyour writing, editing and debuggingof Action! p:I}rograms many times fasterand easier.In this file, when I use somethinglike this: M That means to press the Co:J}ntrol, theShift and the M keys at the sametime. And we all know that doingthat will take us into the monitor.There are :K}more commands to helpyou than I can possibly list. If Idid it would take me over 100K. I amjust going to cover the ones :L}I usemost. I use almost all the commandsat sometime or another. Please lookat your Action! manual and carefullyread ove:M}r the sections on thesecommands. They are very important.I guess we should dive right in withsome editor commands. You :N}alreadyknow R and W for readingand writing to and from the editor.Pressing - and = (theseare the:O} arrow keys) will jump youaround the editor 1 screen at a time.You can really get around the editorfast using these. If:P} you are looking for a certainword or words in you Action! program,the editor has the F command.Action! will ask you:Q} for the stringto search for. And zip you are thereor a not found message appear. Thisonly searches from the point youa:R}re in, downward. So if you are atthe end of your file, no matterwhat you search for you won't find itbecause there is not:S}hing below it.S will also find a string ofcharacters but it will also replaceit with another string. This willcom:T}e in very handy when we startprogramming for BBS Express! PRO.A word of caution, when yousubstitute, use a word that does:U} nothave the old string contained in it.Let's say you want to change all theoccurences of the word 'score' in your progr:V}am into 'u_score'. Changingthe first occurence is great. Thecursor will be on the 'u' in 'u_score'.The next occurence i:W}t will find is the'score' in 'u_score' so you will get 'u_u_score'.If you change a existing line but havenot yet pressed:X} the RETURN key,U will restore it back as goodas new.To delete a line just press . To delete:Y} a bunch ofline just hold this key down. Oh no!You just deleted the wrong line, wellP will put the entire block of:Z}deleted lines back.This is also how you move and copyblocks of text. Just delete them,and go to where you want to appear:[}.Press P and it is moved.If you just want a copy somewhereelse, make sure you P it inthe same spot where you:\} deletedit, the move and P again.To erase you file, does the trick.Remember, look in the Action! ma:]}nualand read over the commands I did notcover. They are very useful!Now the monitor. You already knowthe C command com:^}piles a Action!program and R runs it.B reboots the Action! system withouthaving to turn your computer off andon. This e:_}rases anything you havein the editor and starts you fromscratch.O takes you to the options menu. Inhere you can change :`}some featuresof the Action! system and also turnon some debugging flags.The first option is the Displayoption. When you:a} turn this on,it speeds up reading and writingto the disk and printer. It alsospeeds up compiling your program. Itdoes :b}this by turning the screen offwhile doing these operations. Thefirst thing I always do then I loadmy Action! cartridge it:c} turn thison.If that stupid bell is driving younuts every time you go to the monitoror come across an error while co:d}mpiling, the Bell flag can turnthis off.The Case Insensitive flag can turnon the.... well I better show you.In Action!,:e} the variables: score Score SCORE sCoReare all the same. Turning this onw:f}ill make them all differentvarialbles. It will also make youspell the Action! routines correctlytoo. PrintE is spelled w:g}ith acap P and a cap E. If this is off,the default, you can spell it anyway.The Trace flag prints the PROCor FUNC you a:h}re currently enteringwhen you run your program. We haven'tcovered PROCs and FUNCs yet but Iwill say this is VERY, VERY us:i}efulwhen debugging.Most of the time when Action! findsan error while it is compiling, itwill take you right to the spot :j}in theeditor where the error occured.Sometimes Action! doesn't know wherethe error is and setting List to y will print ea:k}ch line to the screenwhile that line if being compiled.This in only useful when theDisplay flag is on. Compile a sample :l}program with this on tosee what it does.Window size, Line size and Left marginwe won't go into.EOF character will chang:m}e the lastcharacter of each line from a blankspace to something you can see.The Action! manual say it will "aidvisualizat:n}ion of the program."That's it for the Options menu. Backto the monitor commands. D willtake you to DOS. If you areusi:o}ng DOS 2.0 or 2.5 the editorwill be erased so be sure to saveit before you use this. If you haveDOS XL or SpartaDOS, the :p}editorremains. To get back to Action! fromDOS use the B (to cartridge) commandin DOS 2.0-2.5 and CAR in DOS XL andSparta:q}DOS.You can compile a Action! sourceprogram without having to loadit into the editor. Just put a filename after the C f:r}or compile.Make sure you use the whole filenameand device and make sure there are"quotes" on both ends of the filename.C:s} "D:APROG.402"will compile APROG.402 off disk drive#1. This is useful when your programwon't compile because it is out o:t}fmemory.W "D:MYPROG.CMD" will write thecompiled code to disk. That wayyou don't have to recompile it eachtime. Using :u}R "D:MYPROG.CMD" willload and run your Action! program ifit was saved using W.If you have the Action! runtimepackage, th:v}is is how you write programs that don't need the cart.to run.This is also how you save BBS Express!PRO command mod:w}ules.Well that's about it for now. I havebarely scratched the surface with thenumber of commands you have availableto y:x}ou. But, These bare minimums willhelp you get around easier. surface with thenumber of commands you have availableto y8A